#include "client.h"

namespace  client
{
  //1.***********************************对客户端进行初始化*********************.
  //****************************************************************************.
  int Client::Init_Client(const std::string &ip,const short & port)
  {
    //(a)先进行创建socket
    _sock = socket(AF_INET,SOCK_DGRAM,0);
    if(_sock < 0)
    {
      perror("socket");
      return -1;
    }
    //(b)再进行设置服务器的信息
    _server_addr.sin_family = AF_INET;
    _server_addr.sin_addr.s_addr = inet_addr(ip.c_str());
    _server_addr.sin_port = htons(port);

    return 0;
  }

  //2.**********************************设置客户端信息**************************
  //****************************************************************************
  //此处的客户端信息为每次客户端登陆的时候，自己输入的信息
  //信息包含用户的姓名、性别和年龄 
  int Client::Set_Client_Info(const std::string & name,const std::string & gender,const std::string & age)
  {
    _name = name;
    _gender = gender;
    _age = age;
    
    server::Msg msg;
    msg.name = _name;
    msg.gender = _gender;
    msg.age = _age;
   
    return 0;
  }

  //3.*********************************向服务器发送消息************************
  //***************************************************************************
  int Client::Send_Msg(const std::string &info)
  {
    //(a)这里需要按照自定义的协议将输入信息进行序列化
    server::Msg msg;
    msg.name = _name;
    msg.gender = _gender;
    msg.age = _age;
    //如果客户端输入的消息为要退出的状态
   //就对cmd进行设置
    if(info == "quit" || info == "Q" || info == "exit")
    {
      msg.cmd = "quit";
    }
    else
    {
      //正常发送消息
      msg.words = info;
    }
    //用str来保存序列化之后的消息
    std::string str;
    //进行序列化
    msg.Serialize(str);

    //(b)向服务器发送数据
    ssize_t ret = sendto(_sock,(void *)str.c_str(),str.size(),0,(sockaddr *)&_server_addr,sizeof(_server_addr));
    if(ret < 0)
    {
      perror("sendto");
      return -1;
    }
    return 0;
  }

  //4.*********************************接收服务器发来的消息*********************
  //****************************************************************************
  int Client::Recv_Msg(server::Msg & msg)
  {
    //(a)将接收到的消息进行反序列化
    
    char buf[1024 * 10] = {0};
    socklen_t addr_len = sizeof(_server_addr);
    ssize_t recv_size = recvfrom(_sock,buf,sizeof(buf)/sizeof(buf[0]),0,(sockaddr *)&_server_addr,&addr_len);
    if(recv_size < 0)
    {
      perror("recvfrom");
      return -1;
    }
    
    msg.UnSerialize(buf);
    //收到消息后不用打印,交给窗口来处理
    //std::cout<<"["<<msg.name<<"|"<<msg.gender<<"|"<<msg.age<<"]"<<":"<<msg.words<<std::endl;
    
    return 0;
  }

}// end client namespace
